/* -*- c++ -*- */
#ifndef __PhysicsManager_h_
#define __PhysicsManager_h_

#include <btBulletDynamicsCommon.h>
#include "GLDebugDrawer.h"

#include <iostream>
#include <iomanip>

#include <vector>

#include "Punto.h"
#include "Object.h"

#include "CollisionFilter.h"

class PhysicsManager {

 public:

  PhysicsManager(void);
  ~PhysicsManager(void);
		
  void setTimePhysicsPrev(unsigned long time);

  void updatePhysics(unsigned long timePhysicsCurr);
  void stepWorld(float timeSinceLastCall);
  void stepDebuger(void);

  btDiscreteDynamicsWorld* getWorld(void);

  btRigidBody* create_plane(btVector3& normal, float offset = 0.0f, float mass = 0.0f);
  btRigidBody* create_convex_hull(std::vector<Punto>& points, float mass = 0.0f);
  btRigidBody* create_cylinder(Object* obj, float mass = 0.0f);
  btRigidBody* create_cylinder(btVector3& measures, btVector3& origin, float mass = 0.0f);
  btRigidBody* create_box(Object* obj, float mass = 0.0f);
  btRigidBody* create_box(btVector3& measures, btVector3& origin, float mass = 0.0f);
  btRigidBody* create_sphere(float radius, btVector3& origin, float mass);
  btRigidBody* create_rigid_body(btCollisionShape* shape, float mass);
  void add_rigid_body(btRigidBody* body, short group, short mask);
  void add_constraint(btTypedConstraint* constraint);
  void remove_constraint(btTypedConstraint* constraint);

  btRigidBody* ray_test(Punto& from, Punto& to, short groupFilter);
  bool ray_test_hit_point(btVector3 &from, btVector3 &to, short groupFilter, btVector3& hitPoint);
  btRigidBody* ray_test(btVector3& from, btVector3& to, short groupFilter);

 private:

  /****************************************/
  /* THE BULLET WORLD */
  /****************************************/

  btBroadphaseInterface* mBroadphase;
  btDefaultCollisionConfiguration* mCollisionConfig;
  btCollisionDispatcher* mDispatcher;
  btSequentialImpulseConstraintSolver* mSolver;
  btDiscreteDynamicsWorld *dWorld;
  GLDebugDrawer *dbDrawer;

  unsigned long timePhysicsPrev;

  /****************************************/
  void initPhysicsWorld(void);
  void destroyWorld(void);

  
};

#endif
